package com.tdd;

import java.math.BigDecimal;

public class RpnCalculator {
	private HpStack values = new HpStack();

	public BigDecimal peek() {
		return values.peek();
	}

	public void push(BigDecimal value) {
		values.push(value);
	}

	public BigDecimal pop() {
		return values.pop();
	}

	private void minus() {
		BigDecimal rhs = pop();
		BigDecimal lhs = pop();
		BigDecimal result = lhs.subtract(rhs);
		push(result);
	}

	private void plus() {
		BigDecimal rhs = pop();
		BigDecimal lhs = pop();
		BigDecimal result = lhs.add(rhs);
		push(result);
	}

	private void factorial() {
		BigDecimal operand = pop();

		switch (BigDecimal.ZERO.compareTo(operand)) {
		case 1:
			throw new RuntimeException("No Factorial for Negative Numbes");
		case 0:
			push(BigDecimal.ONE);
			return;
		case -1:
			BigDecimal result = BigDecimal.ONE;
			while (BigDecimal.ONE.compareTo(operand) < 0) {
				result = result.multiply(operand);
				operand = operand.subtract(BigDecimal.ONE);
			}

			push(result);
		}
	}

	public void execute(String operatorName) {
		if ("-".equals(operatorName))
			minus();
		else if ("!".equals(operatorName))
			factorial();
		else if ("+".equals(operatorName))
			plus();
		else
			throw new RuntimeException(String.format("%s - unknown operator",
					operatorName));
	}
}
